home *** CD-ROM | disk | FTP | other *** search
- // BPINT Plugs for TRW2000 for Windows 9x
- // Copyright (C) , 1999-2000 ,
- //
- // Author:
- // Zhunanhao, reached at nhzhu@163.net
- //
- // History :
- // 2000.2.23 Zhunanhao write origin code
- //
- // Note:
- // This is only a DEMO ! And testing NOT completed, do NOT use BPINT 3, or it'll crash!
- //
- // Please, DO NOT develop any breakpoint plug-ins now! Because we are
- // developing breakpoint-system now, all interface of breakpoint-system
- // maybe changed!
- //
-
- #include <wdm.h>
- #include "..\INCLUDE\PLUGS.H"
-
- // prototypes
-
- EXC NTSTATUS
- DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
-
- VOID
- PLUGS_Unload(IN PDRIVER_OBJECT DriverObject);
-
-
- NTSTATUS
- DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
- {
- NTSTATUS ntStatus = STATUS_SUCCESS;
-
- DriverObject->DriverUnload = PLUGS_Unload;
-
- return ntStatus;
- }
-
- VOID
- PLUGS_Unload(IN PDRIVER_OBJECT DriverObject)
- {
- }
-
- /****************** WDM Rountine End ****************/
-
- // prototype
-
- BOOL cmd_BPINT( int argc,char** argv ) ;
-
- // end
-
- PLUGS_API* api = 0 ;
- // Call TRW2000 API must like this:
- // api->Add_Command ( ) ;
-
- EXC EXPORT BOOL Plugs_Init ( PLUGS_API* plugsapi)
- {
- api=plugsapi;
-
- api->Add_Command ( "BPINT" , "interrupt-number" ,
- "Breakpoint on interrupt" ,
- "BPINT 3\tBPINT 21",
- cmd_BPINT ) ;
-
- api->dprintf ( "BPINT Plugs Ver 0.01 Initialized..." ) ;
-
- return TRUE ;
- }
-
- EXC EXPORT BOOL Plugs_Exit ( )
- {
- return TRUE ;
- }
-
- /***************** Command ***************/
-
-
- // Command : NPINT
- // NOTE:
- // This is only a demo, it DO NOT call any breakpoint-system function of TRW2000,
- // so you can not use BC to clear it. It's not a real breakpoint that recognized
- // by TRW2000.
- // It's too bad. But maybe it will be improved. We'll change the breakpoint-system
- // of TRW2000. Export more functions.
- //
- // Now use -R to clear it.
- //
-
- WORD IntBPid=0x1000;
-
- BOOL myIntBPhandle()
- {
- if( *(api->pActive_BP_ID)!=IntBPid )
- return FALSE;
- // Does the action "Enter Kernel" caused by breakpoint?
- // Is yes, Active_BP_ID include the id of breakpoint,
- // or Active_BP_ID is 0xFFFF.
-
- api->unhook(api->hh_PreEnterKernel,myIntBPhandle);
- api->DeleteBP((BYTE)IntBPid);
- return FALSE;
- // In the step "PreEnterKernel", you have a chance to prevent to enter kernel,
- // if you return TRUE, TRW2000 will exit to kernel directly. Or return FALSE,
- // TRW2000 will be actived.
- }
-
- DWORD HookIntNum=0xFFFFFFFF;
-
- BOOL myinthandler(DWORD intnum)
- {
- if( HookIntNum!=intnum )
- return FALSE;
- // Return FALSE means that put this interrupt to the next handler.
- // If there is no next handler, TRW2000 will pass this interrupt
- // to Windows.
-
- if( api->GetTraceFlag()==TRUE )
- return FALSE;
- // what is GetTraceFlag? If user use F8(T) to trace program, this flag will be set,
- // When user press F8, we can NOT capture the interrupt.
- if( *(api->pfSoft_1Step)==TRUE )
- return FALSE;
- // what is fSoft_1Step? It means that some part of TRW2000( maybe a plug-ins) need that
- // the code debugged run one step then return to TRW2000. For example, breakpoint-system
- // set this to set INT 3. In this state, we can NOT capture the interrupt too!
- // The difference of fSoft1_Step and TraceFlag is TraceFlag is readable, fSoft_1Step is
- // full-access. You can set it to do some special functions. But must be carefully, we
- // recommend you e-mail us first to get advanced document, if you want to use fSoft_1Step.
-
- // Add your check proc here.
- // e.g:
- // if( api->pUser->CRS.Client_EAX!=0x12345678 )
- // return FALSE;
- // This means that if EAX of code debugged is not 0x12345678, TRW2000 will not be active.
- //
- // And, you can add your "DO" code here.
- // e.g:
- api->dprintf("Break due on interrupt %02X",intnum);
- // This means print a line to command window.
-
- api->Set_Enter_Kernel();
- // Active TRW2000!
-
- ADDRE addr;
- BYTE opcode;
- BYTE opdata;
- BOOL fFault=FALSE;
-
- api->CurCSEIP(&addr);
- addr._off--;
- if( api->PeekB(&addr,&opdata)==FALSE ) // Can readable?
- fFault=TRUE;
- addr._off--;
- if( api->PeekB(&addr,&opcode)==FALSE ) // Can readable?
- fFault=TRUE;
-
- if( intnum==3 && opdata==0xcc && fFault==FALSE) { // Is INT 3?
- api->pUser->CRS.Client_EIP--;
- return FALSE;
- }
-
- if( opcode==0xcd && opdata==intnum && fFault==FALSE ) { // Is INT xx?
- api->pUser->CRS.Client_EIP-=2;
- return FALSE;
- }
-
- // Now, we need to handle hardware interrupt and fault interrupt, because
- // in these status we can not see any code like "INT xx"
- DWORD intseg;
- DWORD intoff;
- BOOL gatesize;
- api->Get_Origin_Interrupt_Vector(intnum,&intseg,&intoff,&gatesize);
- addr._seg=(WORD)intseg;
- addr._off=intoff;
-
- IntBPid=api->addBPInt3(&addr,BP_IMMED);
- api->hook(api->hh_PreEnterKernel,myIntBPhandle,0);
- // Ok, we set a breakpoint on the entry point of Windows's ISRs,
- // Now we can let's go!
-
- return FALSE;
- // Return TRUE means that prevent TRW2000 to pass the interrupt to next handler
- // or Windows. It tell TRW2000 that the handling of interrupt has completed.
- // When this function return, TRW2000 will check that whether need to active
- // TRW2000. If yes, TRW2000 will pop-up. If no, there is nothing will be happened.
- // Why we return FALSE here?
- // Because we need to pass the interrupt to Windows! We can't handle INT21H AH=3FH!
- }
-
- BOOL cmd_BPINT( int argc,char**argv )
- {
- DWORD Intnum;
- if( argc!=1 )
- return FALSE;
-
- if( api->strcmp(argv[0],"-R")==0 ) {
- api->unhook(api->hh_IntObj+HookIntNum*4,myinthandler);
- // Remove the interrupt handler. TRW2000 will modify IDT and restore
- // the origin interrupt vector.
- // Ues API api->UpdateIDT() to make the modification done immediately.
- HookIntNum=0xFFFFFFFF;
- return TRUE;
- }
-
- if( HookIntNum!=0xFFFFFFFF ) {
- api->dprintf("BPINT only can be use once.");
- return TRUE;
- }
-
- PSTR s=api->str2hex(argv[0],&Intnum);
- if( *s!=0 )
- return FALSE;
-
- HookIntNum=Intnum;
- api->hook(api->hh_IntObj+HookIntNum*4,myinthandler,0);
- // Add a interrupt handler. TRW2000 will modify IDT
- // and hook this interrupt.
- // Ues API api->UpdateIDT() to make the modification done immediately.
-
- return TRUE;
- }